import { HonoContext } from '../types/hono';
import { User } from '../types/db';

interface KVMetadata {
    expirationTtl?: number;
}
// Token 相关的常量配置
const TOKEN_CONFIG = {
    EXPIRE_DAYS: 10,
    REFRESH_THRESHOLD_DAYS: 5,
    // 秒为单位
    get EXPIRE_TTL() { return 60 * 60 * 24 * this.EXPIRE_DAYS },
    get REFRESH_THRESHOLD_TTL() { return 60 * 60 * 24 * this.REFRESH_THRESHOLD_DAYS }
} as const;

export async function generateToken(c: HonoContext, userID: string) {
    try {
        // 生成更安全的随机token: 随机值 + 用户ID + 时间戳
        const randomPart = Math.random().toString(36).substring(2);
        const userPart = userID;
        const timestampPart = Date.now().toString(36);
        const token = `${randomPart}${userPart}${timestampPart}`;

        // 写入KV, 过期时间10天
        await c.env.KV.put(token, userID.toString(), { 
            expirationTtl: TOKEN_CONFIG.EXPIRE_TTL 
        });
        return token;
    } catch (error) {
        console.error('Token generation failed:', error);
        throw new Error('Failed to generate token');
    }
}

export async function validateToken(c: HonoContext, token: string) {
    
    const { value: userId, metadata } = await c.env.KV.getWithMetadata<KVMetadata>(token);
    
    if (!userId) {
        return null;
    }

    // 过期时间小于5天增长到10天
    if (metadata?.expirationTtl && metadata.expirationTtl < TOKEN_CONFIG.REFRESH_THRESHOLD_TTL) {
        await c.env.KV.put(token, userId, { 
            expirationTtl: TOKEN_CONFIG.EXPIRE_TTL 
        });
    }

    // 查询用户信息
    const user = await c.env.DB.prepare(
        'SELECT * FROM users WHERE id = ?'
    ).bind(parseInt(userId)).first<User>();

    if (!user) {
        // 如果用户不存在，清除token
        await invalidateToken(c, token);
        return null;
    }

     return user;
    
}

export async function invalidateToken(c: HonoContext, token: string) {
    try {
        await c.env.KV.delete(token);
    } catch (error) {
        console.warn('Token invalidation failed:', error);
    }
}

export async function authMiddleware(c: HonoContext, next: Function) {
    try {
        const authHeader = c.req.header('Authorization');
        if (!authHeader) {
            return c.json({ error: 'Authorization header is required' }, 401);
        }

        const [scheme, token] = authHeader.split(' ');
        if (scheme !== 'Bearer' || !token) {
            return c.json({ error: 'Invalid authorization format. Use: Bearer <token>' }, 401);
        }

        const user = await validateToken(c, token);
        if (!user) {
            return c.json({ error: 'Invalid or expired token' }, 401);
        }

        // 将用户信息存储到上下文中
        c.set('user', user);
        await next();
    } catch (error) {
        console.warn('Auth middleware error:', error);
        return c.json({ error: 'Authentication failed' }, 500);
    }
}

